<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div>
	<h2>光线跟踪技术 第一周</h2>
	<h4>球体</h4>
	<br>
	<canvas id="canvas0" height="240" width="480">你的浏览器不支持canvas！</canvas>
</div>
<script>
	function vec_dot(vec0, vec1){
		console.assert(vec0.length == vec1.length)
		let s = 0
		for(let i = 0; i < vec0.length; i++){
			s += vec0[i] * vec1[i]
		}
		return s
	}

	function norm(vec){
		let n = 0
		for(let i = 0; i < vec.length; i++)
			n += vec[i] ** 2
		n = Math.sqrt(n)
		return n		
	}

	function unit_vector(vec){
		let n = norm(vec)
		vec1 = []
		for(let i = 0; i < vec.length; i++)
			vec1[i] = vec[i] / n
		return vec1
	}

	function distance(line, center){
		console.assert(line.length == 6)
		let x0 = line[0], y0 = line[1], z0 = line[2]
		let vx = line[3], vy = line[4], vz = line[5]
		let x1 = center[0], y1 = center[1], z1 = center[2]
		let v1 = [vx, vy, vz]
		let v2 = [x1 - x0, y1 - y0, z1 - z0]
		let n1 = norm(v1), n2 = norm(v2)
		let cos_theta = vec_dot(v1, v2) / n1 / n2
		let theta = Math.acos(cos_theta)
		let d = n2 * Math.sin(theta)
		return d
	}

	function color(vec){
		if(distance(
			[0, 0, 0, vec[0], vec[1], vec[2]],
			[-0.12, 0, 1]
			) < 0.5)
			//击中球体
			return [1, 0, 0]
		let uv = unit_vector(vec)
		let t = 0.5 * (1 - uv[1])
		return [1 - 0.5 * t, 1 - 0.3 * t, 1]
	}

	(function(){
		let canvas = document.getElementById('canvas0')
		let ctx = canvas.getContext('2d')
		let width = canvas.width
		let height = canvas.height
		let imageData = ctx.getImageData(0, 0, width, height)
		let data = imageData.data
		let start = [-2, -1, -1]
		for(let i = 0; i < width; i++){
			for(let j = 0; j < height; j++){
				let px = j * width + i
				let u = i / width
				let v = j / height
				let ray = [
					start[0] + u * 4,
					start[1] + v * 2,
					start[2]
					]
				let c = color(ray)
				data[px * 4 + 0] = 255 * c[0]
				data[px * 4 + 1] = 255 * c[1]
				data[px * 4 + 2] = 255 * c[2]
				data[px * 4 + 3] = 255
			}
		}
		ctx.putImageData(imageData, 0, 0)


	})()
</script>
</body>
</html>